package fr.inserm.u915.tabixserver;

import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;


public class Build extends ListOfInstances
	{
	private File fastaFile;
	private File baseDir;
	private int taxonId=9606;//human
	private Map<String,Instance> id2instance=new HashMap<String,Instance>();
	Build()
		{
		}
	
	void setFastaFile(File fastaFile)
		{
		this.fastaFile = fastaFile;
		}
	
	public File getFastaFile()
		{
		return fastaFile;
		}
	
	public int getTaxonId()
		{
		return taxonId;
		}
	
	void setTaxonId(int taxonId)
		{
		this.taxonId = taxonId;
		}
	
	void setBaseDir(File baseDir)
		{
		this.baseDir = baseDir;
		}
	public File getBaseDir() {
		return baseDir;
		}
	
	@Override
	void addInstance(Instance i)
		{
		super.addInstance(i);
		this.id2instance.put(i.getId(), i);
		}
	
	
	
	public void writeXsd(XMLStreamWriter w) throws XMLStreamException
		{
		w.writeStartElement(XSD.prefix,"schema",XSD.NS);
		w.writeAttribute("xmlns:"+XSD.prefix, XSD.NS);
		w.writeAttribute("xmlns:"+XSI.prefix, XSI.NS);
		w.writeAttribute("xmlns:"+TNS.prefix, TNS.NS);
		w.writeAttribute("targetNamespace", TNS.NS);
		w.writeAttribute("elementFormDefault","qualified");
		
		//TABIX
		w.writeStartElement(XSD.prefix,"complexType",XSD.NS);
		w.writeAttribute("name","tabixType");
		XSD.writeAnnotation(w, "Root element");
		w.writeStartElement(XSD.prefix,"sequence",XSD.NS);
		w.writeEmptyElement(XSD.prefix,"element",XSD.NS);
		w.writeAttribute("name","instance");
		w.writeAttribute("type",TNS.prefix+":instanceType");
		w.writeAttribute("minOccurs","0");
		w.writeAttribute("maxOccurs","unbounded");
		w.writeEndElement();
		w.writeEndElement();//complexType

		w.writeStartElement(XSD.prefix,"element",XSD.NS);
		w.writeAttribute("name","tabix");
		w.writeAttribute("type",TNS.prefix+":"+"tabixType");
		w.writeEndElement();
		
		w.writeComment("=============================================");

		//TNS:instance
		w.writeStartElement(XSD.prefix,"complexType",XSD.NS);
		w.writeAttribute("name","instanceType");
		
		w.writeStartElement(XSD.prefix,"sequence",XSD.NS);
		w.writeEmptyElement(XSD.prefix,"element",XSD.NS);
		w.writeAttribute("name","query");
		w.writeAttribute("type",TNS.prefix+":queryType");
		w.writeAttribute("minOccurs","0");
		w.writeAttribute("maxOccurs","unbounded");
		w.writeEndElement();
		
		for(String s:new String[]{"id","label","description","build"})
			{
			XSD.defineAttribute(w,s, XSD.prefix+":string");
			}
		w.writeEndElement();
		
		w.writeStartElement(XSD.prefix,"element",XSD.NS);
		w.writeAttribute("name","instance");
		w.writeAttribute("type",TNS.prefix+":"+"instanceType");
		w.writeEndElement();
		
		w.writeComment("=============================================");
		
		//TNS:queryType
		w.writeStartElement(XSD.prefix,"complexType",XSD.NS);
		w.writeAttribute("name","queryType");
		
		w.writeStartElement(XSD.prefix,"sequence",XSD.NS);
		w.writeEmptyElement(XSD.prefix,"element",XSD.NS);
		//w.writeAttribute("name","query");
		w.writeAttribute("ref",TNS.prefix+":"+Instance.ABSTRACT_CHROM_START_END);
		w.writeAttribute("minOccurs","0");
		w.writeAttribute("maxOccurs","unbounded");
		w.writeEndElement();
		
		
		XSD.defineAttribute(w,"chrom", XSD.prefix+":string");
		XSD.defineAttribute(w,"start", XSD.prefix+":int");
		XSD.defineAttribute(w,"end", XSD.prefix+":int");
		
		
		w.writeEndElement();
		
		w.writeComment("=============================================");
		
		
		
		writeXsdBody(w);
		w.writeEndElement();
		}
	
	
	public void writeXsdBody(XMLStreamWriter w) throws XMLStreamException
		{
		w.writeStartElement(XSD.prefix,"complexType",XSD.NS);
		w.writeAttribute("name",Instance.ABSTRACT_CHROM_START_END);
		XSD.defineAttribute(w, "chrom", XSD.prefix+":string");
		XSD.defineAttribute(w, "start", XSD.prefix+":int");
		XSD.defineAttribute(w, "end", XSD.prefix+":int");
		
		w.writeStartElement(XSD.prefix, "attribute", XSD.NS);
		w.writeAttribute("name", "index");
		w.writeAttribute("type", XSD.prefix+":int");
		w.writeAttribute("use","optional");
		w.writeEndElement();
		
		
		w.writeEndElement();
		
		
		
		
		
		
		w.writeStartElement(XSD.prefix,"element",XSD.NS);
		w.writeAttribute("name",Instance.ABSTRACT_CHROM_START_END);
		w.writeAttribute("type",TNS.prefix+":"+Instance.ABSTRACT_CHROM_START_END);
		w.writeEndElement();
		
		List<Instance> instances=getAllInstances();
		Set<String> tableIds=new HashSet<String>(instances.size());
				
		for(Instance i:instances)
			{
			if(!tableIds.contains(i.getTable().getId()))
				{
				tableIds.add(i.getTable().getId());
				i.getTable().writeXsd(w);
				}
			i.writeXsd(w);
			}
		}
	
	}
